package com.ums.scumspay.service.impl;

import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ums.scumspay.constant.MerInfoConstant;
import com.ums.scumspay.constant.PayOrderNoConstant;
import com.ums.scumspay.entity.req.c2b.GetQrCodeBody;
import com.ums.scumspay.entity.req.c2b.RefundBody;
import com.ums.scumspay.service.CtoBService;
import com.ums.scumspay.sync.PayOrderSync;
import com.ums.scumspay.utils.CounterSignUtils;
import com.ums.scumspay.utils.RandomUtils;
import com.ums.scumspay.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class CtoBServiceImpl implements CtoBService {

    String appId= MerInfoConstant.c2bAppId;

    String appKey=MerInfoConstant.c2bAppKey;

    String mid=MerInfoConstant.mid;

    String tid=MerInfoConstant.tid;

    // String qrCodeId="1000276623322401714636815811";

    String urlNotify=MerInfoConstant.urlNotify;

    @Override
    public String sendPayRequest(String extOrderNo,String payAmount) {
        // String extOrderNo ="8888"+new SimpleDateFormat("yyyyMMddmmHHssSSS").format(new Date())+RandomUtils.getRandomNum(7);
        String qrCodeId = UUIDUtil.getUUID();
        GetQrCodeBody body = GetQrCodeBody.builder()
                .requestTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .mid(mid)
                .tid(tid)
                .notifyUrl(urlNotify+"?extOrderNo="+extOrderNo+"-2")
                .returnUrl("http://yewu.sc-ums.com:8090/#/check?extOrderNo="+extOrderNo)
                .instMid("QRPAYDEFAULT")
                .qrCodeId(qrCodeId)
                .billDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
                .billNo(extOrderNo)
                .totalAmount(Integer.parseInt(payAmount))
                .secureTransaction("false").build();
        String authorization = null;
        try {
            authorization = CounterSignUtils.getOpenBodySig(appId, appKey, JSONUtil.toJsonStr(body));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String url="https://test-api-open.chinaums.com/v1/netpay/bills/get-qrcode";
        String request = request(url, authorization, JSONUtil.toJsonStr(body));
        log.info("支付响应：{}",request);
        // Map<String,Integer> map = PayOrderNoConstant.getMap().get("c2b");
        // if (map==null){
        //     map=new HashMap<>();
        // }
        // map.put(extOrderNo,1);
        // PayOrderNoConstant.getMap().put("c2b",map);
        return (String) JSONUtil.toBean(request,Map.class).get("billQRCode");
    }

    public static void main(String[] args) throws Exception{
        // System.out.println(new CtoBServiceImpl().sendPayRequest(UUIDUtil.getUUID().substring(0,30), "1"));
        // new CtoBServiceImpl().sendQueryPayResult("ab9ca13c118a4869b28f45f538fbf9");
        new CtoBServiceImpl().sendCancelRequest("8888202309224013328621084162","1");
    }

    @Override
    public Map<String, String> sendQueryPayResult(String extOrderNo) {
        GetQrCodeBody body = GetQrCodeBody.builder()
                .requestTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .mid(mid)
                .tid(tid)
                .instMid("QRPAYDEFAULT")
                .billDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
                .billNo(extOrderNo)
                .build();
        String authorization = null;
        try {
            authorization = CounterSignUtils.getOpenBodySig(appId, appKey, JSONUtil.toJsonStr(body));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String url="https://test-api-open.chinaums.com/v1/netpay/bills/query";
        String request = request(url, authorization, JSONUtil.toJsonStr(body));
        log.info("查询c2b：{}",request);
        try{
            return JSONUtil.toBean(new JSONObject(request), Map.class);
        }catch (JSONException e){
            throw new RuntimeException();
        }
    }

    @Override
    public Map<String,String> sendCancelRequest(String extOrderNo, String refundAmount){
        int amt=(int) (Double.parseDouble(refundAmount)*100.0);
        RefundBody body = RefundBody.builder()
                .requestTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
                .mid(mid)
                .tid(tid)
                .instMid("QRPAYDEFAULT")
                .billDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
                .billNo(extOrderNo)
                .refundAmount(amt)
                .build();
        String authorization = null;
        try {
            authorization = CounterSignUtils.getOpenBodySig(appId, appKey, JSONUtil.toJsonStr(body));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String url="https://test-api-open.chinaums.com/v1/netpay/bills/refund";
        String request = request(url, authorization, JSONUtil.toJsonStr(body));
        log.info("退款响应：{}",request);
        return JSONUtil.toBean(request,Map.class);
        // if (request!=null && JSONUtil.toBean(request,Map.class).containsKey("billStatus") && JSONUtil.toBean(request,Map.class).get("billStatus").equals("REFUND"))
        //     return true;
        // return false;
    }


    /**
     * 发送http请求
     * @param url 请求url
     * @param authorization 认证报文
     * @param reqBody  请求体
     * @return response
     */
    static String request(String url, String authorization, String reqBody){
        String response = "";
        PrintWriter out = null;
        BufferedReader in = null;
        try{
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            HttpURLConnection httpUrlConnection = (HttpURLConnection) conn;
            httpUrlConnection.setRequestProperty("Content-Type", "application/json");
            httpUrlConnection.setRequestProperty("authorization",authorization);
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setDoInput(true);
            out = new PrintWriter(httpUrlConnection.getOutputStream());
            out.write(reqBody);
            out.flush();
            httpUrlConnection.connect();
            in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                response += line;
            }
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            try {
                if (out != null) { out.close();}
                if (in != null) {in.close();}
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return response;
    }
}
